﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MegavaniaX;
using MegavaniaX.Messaging.Events;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace MegavaniaX.InputProcessor
{
    public class DefaultInputProcessor : IInputProcessor
    {

        public const float ZoomDivisor = 1500.0f;

        public KeyboardState OldKeyState
        {
            get;
            private set;
        }

        public MouseState OldMouseState
        {
            get;
            private set;
        }

        public DefaultInputProcessor()
        {
            // Kind of breaking encapsulation here, but w/e.
            OldKeyState = Keyboard.GetState();
            OldMouseState = Mouse.GetState();
        }

        /// <summary>
        /// Default input processor, used temporarily I guess.
        /// </summary>
        /// <param name="keyState"></param>
        public void ProcessInput(KeyboardState keyState, MouseState mouseState, TimeSpan elapsedTime)
        {
            // Move right
            if (keyState.IsKeyDown(Keys.Right) && !OldKeyState.IsKeyDown(Keys.Right))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.MoveRightPressed, elapsedTime, null));
            }
            if (keyState.IsKeyUp(Keys.Right) && !OldKeyState.IsKeyUp(Keys.Right))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.MoveRightReleased, elapsedTime, null));
            }

            // Move left
            if (keyState.IsKeyDown(Keys.Left) && !OldKeyState.IsKeyDown(Keys.Left))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.MoveLeftPressed, elapsedTime, null));
            }
            if (keyState.IsKeyUp(Keys.Left) && !OldKeyState.IsKeyUp(Keys.Left))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.MoveLeftReleased, elapsedTime, null));
            }

            // Jump
            if (keyState.IsKeyDown(Keys.Up) && !OldKeyState.IsKeyDown(Keys.Up))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.JumpPressed, elapsedTime, null));
            }
            if (keyState.IsKeyUp(Keys.Up) && !OldKeyState.IsKeyUp(Keys.Up))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.JumpReleased, elapsedTime, null));
            }

            // grasp ladder
            if (keyState.IsKeyDown(Keys.A) && !OldKeyState.IsKeyDown(Keys.A))
            {
                MessagingSystem.DispatchEvent(new ClimbEvent(MegavaniaEventType.ClimbPressed, elapsedTime, null));
            }

            // Slide
            if (keyState.IsKeyDown(Keys.D) && !OldKeyState.IsKeyDown(Keys.D))
            {
                MessagingSystem.DispatchEvent(new MovementEvent(MegavaniaEventType.SlidePressed, elapsedTime, null));
            }

            // Shoot gun
            if ((keyState.IsKeyDown(Keys.F) && !OldKeyState.IsKeyDown(Keys.F)) || (keyState.IsKeyDown(Keys.G) && !OldKeyState.IsKeyDown(Keys.G)))
            {
                var modifiers = new Actors.Weapons.WeaponModifiers();
                modifiers.IsLeftPressed = keyState.IsKeyUp(Keys.Left) && !OldKeyState.IsKeyUp(Keys.Left);
                modifiers.IsRightPressed = keyState.IsKeyUp(Keys.Right) && !OldKeyState.IsKeyUp(Keys.Right);
                WeaponType weaponType = WeaponType.Primary;
                if (keyState.IsKeyDown(Keys.G))
                    weaponType = WeaponType.Secondary;
                MessagingSystem.DispatchEvent(new WeaponEvent(MegavaniaEventType.ShootPressed, weaponType, modifiers, null));
            }

            // change weapon!
            if ((keyState.IsKeyDown(Keys.Z) && !OldKeyState.IsKeyDown(Keys.Z)))
            {
                MessagingSystem.DispatchEvent(new WeaponChangeEvent(MegavaniaEventType.WeaponChangeStarted, ChangeWeaponTo.Next, null));
            }

            // Zoom change
            if (mouseState.ScrollWheelValue != OldMouseState.ScrollWheelValue)
            {
                float zoomChange = (mouseState.ScrollWheelValue - OldMouseState.ScrollWheelValue) / ZoomDivisor;
                MessagingSystem.DispatchEvent(new CameraZoomEvent(MegavaniaEventType.CameraZoomChange, elapsedTime, zoomChange));
            }

            // Camera move up
            if (((keyState.IsKeyDown(Keys.LeftShift) || keyState.IsKeyDown(Keys.RightShift)) && keyState.IsKeyDown(Keys.Up))
                && !((OldKeyState.IsKeyDown(Keys.LeftShift) || OldKeyState.IsKeyDown(Keys.RightShift)) && OldKeyState.IsKeyDown(Keys.Up)))
            {
                MessagingSystem.DispatchEvent(new CameraMovementEvent(MegavaniaEventType.CameraMoveUpStart, elapsedTime));
            }

            if (((keyState.IsKeyUp(Keys.LeftShift) || keyState.IsKeyUp(Keys.RightShift)) && keyState.IsKeyUp(Keys.Up))
               && !((OldKeyState.IsKeyUp(Keys.LeftShift) || OldKeyState.IsKeyUp(Keys.RightShift)) && OldKeyState.IsKeyUp(Keys.Up)))
            {
                MessagingSystem.DispatchEvent(new CameraMovementEvent(MegavaniaEventType.CameraMoveUpFinished, elapsedTime));
            }


            // Store old state
            OldKeyState = keyState;
            OldMouseState = mouseState;
        }
    }
}
